#ifndef WSSOCKET_MANAGER_H_
#define WSSOCKET_MANAGER_H_

#include "Common.h"
#include "Resource.h"
#include "ResourceManager.h"
#include "Singleton.h"
#include "String.h"
#include "WSSocket.h"
#include "Threading/ThreadStarter.h"
#include "Threading/QueueThreadPool.h"
#include "BufferPools.h"

//非安全Socket支持
#include "websocketpp/config/asio.hpp"
#include "websocketpp/server.hpp"

//class  WSPacketElement :public Object
class  WSPacketElement
{
public:
        WSPacketElement() {}
        virtual ~WSPacketElement(void);

        void Virtual_Constructor();
        void Virtual_Destructor();

        WSSocketPtr  socket;
        WorldPacket  packet;
};


#ifndef _SOCKET_MANANGER_DEFINE
#define _SOCKET_MANANGER_DEFINE

#define  DEFAULT_SERVER_REQUEST_POOL_SIZE               4096  //default main request queue size
#define WGS_SOCKET_MANAGER_MUTEX_NAME socket_manager_mutex
#define WGS_SOCKET_MANAGER_MUTEX mutable boost::mutex WGS_SOCKET_MANAGER_MUTEX_NAME;
#define WGS_SOCKET_MANAGER_LOCK         boost::lock_guard<boost::mutex>  wgsSocketManagerMutexLock(WGS_SOCKET_MANAGER_MUTEX_NAME);

#define WGS_SOCKET_MANAGER_RW_MUTEX_NAME      socket_manager_read_write_shared_mutex
#define WGS_SOCKET_MANAGER_RW_MUTEX   mutable boost::shared_mutex WGS_SOCKET_MANAGER_RW_MUTEX_NAME;
#define WGS_SOCKET_MANAGER_READ_LOCK             boost::shared_lock<boost::shared_mutex>  wgsSocketSharedMutexLock(WGS_SOCKET_MANAGER_RW_MUTEX_NAME);
#define WGS_SOCKET_MANAGER_WRITE_LOCK             boost::unique_lock<boost::shared_mutex>  wgsSocketWriteMutexLock(WGS_SOCKET_MANAGER_RW_MUTEX_NAME); 

#define WGS_WEBSOCKET_MANAGER_MUTEX_NAME websocket_manager_mutex
#define WGS_WEBSOCKET_MANAGER_MUTEX mutable boost::mutex WGS_WEBSOCKET_MANAGER_MUTEX_NAME;
#define WGS_WEBSOCKET_MANAGER_LOCK         boost::lock_guard<boost::mutex>  wgsWebSocketManagerMutexLock(WGS_WEBSOCKET_MANAGER_MUTEX_NAME);

/*
 *  Socket 关闭锁
 */
#define WGS_SOCKET_CLOSE_MUTEX_NAME socket_manager_close_mutex
#define WGS_SOCKET_CLOSE_MUTEX  mutable boost::mutex WGS_SOCKET_CLOSE_MUTEX_NAME;
#define WGS_SOCKET_CLOSE_LOCK         boost::lock_guard<boost::mutex>  wgsSocketCloseMutexLock(WGS_SOCKET_CLOSE_MUTEX_NAME);

#endif

class  WSSocketManager: public ThreadRunableBase,public ResourceManager,public Singleton<WSSocketManager>
{
	WGS_WEBSOCKET_MANAGER_MUTEX
	WGS_SOCKET_MANAGER_MUTEX
	WGS_SOCKET_MANAGER_RW_MUTEX 
	WGS_SOCKET_CLOSE_MUTEX
public:
	enum tls_mode {
    		MOZILLA_INTERMEDIATE = 1,
    		MOZILLA_MODERN = 2
	};
public:
	WSSocketManager();
	~WSSocketManager();

	
	ResourcePtr  create(int fd,const NameValuePairList* params = 0);
	//web socket create
	ResourcePtr  create(WebSocketHandle webSocketHandle,const NameValuePairList* params = 0);

	//user manager start
	void	Startup(const uint32 &group_id,const uint32 & client_limit,const uint32 & client_timeout,const uint32 & websocket_timeout = 0,const uint32 & ip_limit=0 ,const uint32 & a_limit=0, \
		const uint32 & b_limit=0, const uint32 & c_limit=0);

	void	InitThreadPool(const uint32 & thread_min,const uint32 & thread_max,const uint32 & timeout);


	void	Listen(const char * ListenAddress, uint32 Port);

	void    WebSocketListen(const char * ListenAddress, uint32 Port,bool skip_error = false);
	void    WebSocketTLSListen(const char * ListenAddress, uint32 Port,bool skip_error = false);

	//Httpd Listen
	void	HttpdListen(const String & ListenAddress,uint32 Port,uint32 TLSPort = 0);

	void 	Shutdown(void);

	bool     checkFlood(const uint32 & ip);

	void 	ShowStats(void);
	size_t	getSocketList(std::list<ResourcePtr> & sList);
	
	//得到当前Socket数量
	size_t getSocketCount(void);

	//链接自动更新
	void	Update(const uint32 & p_time);
	
	//添加Socket到自动处理队列
	bool	addSocketProcessQueue(ResourceProxy & socket);
	bool	addSocketProcessQueue(ResourcePtr & socket);

	//virual from  ThreadRunableBase
        bool  run(void *p);


	void AddSocket(WSSocket * s);
	void RemoveSocket(WSSocket * s);

	void WantWrite(WSSocket * s);
	void WantRead(WSSocket * s);
	void MessageLoop();

	//WebSocket 消息循环
	void WebSocketMessageLoop();
	//WebSocket TLS 消息循环
	void WebSocketTLSMessageLoop();

	void setStartRunning(const bool & set)	{	m_start_runing = set;	}

	//注册、取消WebSocket
	
	void AddWebSocket(const WebSocketHandle & webSocketHandle,const ResourceHandle & sockHandle);
	void AddWebSocket(const WebSocketHandle & webSocketHandle,const ResourcePtr & resource);

	void RemoveWebSocket(const WebSocketHandle & webSocketHandle);
	void RemoveWebSocket(const ResourceHandle & sockHandle);
	void RemoveWebSocket(const ResourcePtr & resource);

	ResourceHandle	getWebSocketResourceHandle(const WebSocketHandle & webSocketHandle);
	ResourcePtr	getWebSocketResourcePtr(const WebSocketHandle & webSocketHandle);

	void AddWebSocketTLS(const WebSocketHandle & webSocketHandle,const ResourceHandle & sockHandle);
	void AddWebSocketTLS(const WebSocketHandle & webSocketHandle,const ResourcePtr & resource);

	void RemoveWebSocketTLS(const WebSocketHandle & webSocketHandle);
	void RemoveWebSocketTLS(const ResourceHandle & sockHandle);
	void RemoveWebSocketTLS(const ResourcePtr & resource);

	ResourceHandle	getWebSocketTLSResourceHandle(const WebSocketHandle & webSocketHandle);
	ResourcePtr	getWebSocketTLSResourcePtr(const WebSocketHandle & webSocketHandle);


public:
	typedef std::map<WebSocketHandle,ResourceHandle>	WebSocketHandleMap;
	typedef websocketpp::server<websocketpp::config::asio>  WebSocketServer;
	typedef WebSocketServer::message_ptr		WebSocketMessage;
	typedef WebSocketServer::connection_ptr		WSConnectionPtr;
	typedef websocketpp::server<websocketpp::config::asio_tls>  WebSocketServerTLS;
	typedef WebSocketServerTLS::message_ptr		WebSocketMessageTLS;
	typedef WebSocketServerTLS::connection_ptr		WSConnectionTLSPtr;
	typedef websocketpp::lib::shared_ptr<websocketpp::lib::asio::ssl::context> WSContextTLSPtr;
	
	//WebSocket 处理事件
	void  WebSocket_OnOpen(WebSocketHandle hdl);
	void  WebSocket_OnClose(WebSocketHandle hdl);
	void  WebSocket_OnFail(WebSocketHandle hdl);
	bool  WebSocket_OnValidate(WebSocketHandle hdl);
	void  WebSocket_OnMessage(WebSocketHandle hdl,WebSocketMessage msg);
	void  WebSocket_OnPongTimeout(WebSocketHandle hdl,String msg);
	
	//WebSocket TLS 处理事件
	void  WebSocketTLS_OnOpen(WebSocketHandle hdl);
	void  WebSocketTLS_OnClose(WebSocketHandle hdl);
	void  WebSocketTLS_OnFail(WebSocketHandle hdl);
	bool  WebSocketTLS_OnValidate(WebSocketHandle hdl);
	void  WebSocketTLS_OnMessage(WebSocketHandle hdl,WebSocketMessage msg);
	void  WebSocketTLS_OnPongTimeout(WebSocketHandle hdl,String msg);
	WSContextTLSPtr  WebSocketTLS_OnTLSInit(tls_mode mode,WebSocketHandle hdl);

	//得到WEBSocket网络连接对象
	WSConnectionPtr	getWSConnectionPtr(WebSocketHandle hdl);
	WSConnectionTLSPtr	getWSConnectionTLSPtr(WebSocketHandle hdl);
	
	//发送文本信息
	void WebSocketSend(WebSocketHandle hdl,const String & msg);
	//发送二进制信息
	void WebSocketSend(WebSocketHandle hdl,const void * data, size_t len);
	//关闭 WebSocket 连接
	void WebSocketClose(WebSocketHandle hdl,bool force = false);
	
	//发送文本信息
	void WebSocketTLSSend(WebSocketHandle hdl,const String & msg);
	//发送二进制信息
	void WebSocketTLSSend(WebSocketHandle hdl,const void * data, size_t len);
	//关闭 WebSocket 连接
	void WebSocketTLSClose(WebSocketHandle hdl,bool force= false);
protected:
	uint32		m_group_id;
	bool		m_start_runing;
	
	int 		m_epoll_fd;

	uint32		m_ip_limit;
	uint32		m_net_a_limit;
	uint32		m_net_b_limit;
	uint32		m_net_c_limit;

	uint32		m_client_num_limit;

	//超时时间 TCP,websocket
	uint32		m_client_timeout;
	uint32		m_websocket_timeout;

	WebSocketHandleMap	m_webSocketHandleMap;
	WebSocketHandleMap	m_webSocketTLSHandleMap;

	//WebSocketEngine
	WebSocketServer		m_WebSocketServer;
	WebSocketServerTLS	m_WebSocketServerTLS;

	std::map<uint32,uint32>			m_net_a_map;
	std::map<uint32,uint32>			m_net_b_map;
	std::map<uint32,uint32>			m_net_c_map;
	std::map<uint32,uint32>			m_ip_map;

	void	 registerFlood(const uint32 & ip);
	void	 unRegisterFlood(const uint32 & ip);

	//网络包内存分配池
	//the request queue pool
        tPPoolClass<WSPacketElement,DEFAULT_SERVER_REQUEST_POOL_SIZE>     m_PacketPool;

	//网络线程请求池
	//server main process threadpool
        CQueueThreadPool<WSPacketElement> m_processPool;

	//启动网络数据传送线程
	void SpawnNetworkThreads(void);

	//启动WebSocket 处理线程
	void SpawnWebSocketThreads(void);
	
	//启动WebSocket TLS 处理线程
	void SpawnWebSocketTLSThreads(void);




	String	getSocketStringName(const uint32 & serial);
       /// @copydoc ResourceManager::createImpl
        Resource* createImpl(const String& name, ResourceHandle handle,
            const String& group, bool isManual, ManualResourceLoader* loader,
            const NameValuePairList* createParams);
};

class WorldNetworkEngineThread : public ThreadBase
{
        WSSocketManager * wsm;
public:
        WorldNetworkEngineThread(WSSocketManager * s) :ThreadBase("WorldNetworkEngineThread"),wsm(s) {}
        bool run()
        {
                wsm->MessageLoop();
                return true;
        }
};

class WorldWebSocketMessageThread : public ThreadBase
{
        WSSocketManager * wsm;
public:
        WorldWebSocketMessageThread(WSSocketManager * s) :ThreadBase("WorldWebSocketMessageThread"),wsm(s) {}
        bool run()
        {
                wsm->WebSocketMessageLoop();
                return true;
        }
};

class WorldWebSocketTLSMessageThread : public ThreadBase
{
        WSSocketManager * wsm;
public:
        WorldWebSocketTLSMessageThread(WSSocketManager * s) :ThreadBase("WorldWebSocketTLSMessageThread"),wsm(s) {}
        bool run()
        {
                wsm->WebSocketTLSMessageLoop();
                return true;
        }
};


class WorldHttpdRequestThread : public ThreadBase
{
	String  m_host_and_port;
	String  m_https_host_and_port;
public:
        WorldHttpdRequestThread(const String & listen_host_and_port,const String & listen_https_host_and_port) :ThreadBase("WorldHttpdRequestThread"),m_host_and_port(listen_host_and_port) ,m_https_host_and_port(listen_https_host_and_port){}
        bool run();
};

#define   sWSSocketMgr	   WSSocketManager::getSingleton()

#endif 
